package com.elbis.business.controller.player;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ValueChangeEvent;
import javax.faces.validator.ValidatorException;

import org.apache.log4j.Logger;

import com.elbis.access.wg.api.Constants;
import com.elbis.access.wg.api.request.account.AccountList;
import com.elbis.access.wg.api.request.account.AccountListRequestImpl;
import com.elbis.access.wg.api.request.account.PersonalData;
import com.elbis.access.wg.api.request.account.PersonalDataRequestImpl;
import com.elbis.access.wg.api.response.account.AccountListResponse;
import com.elbis.access.wg.api.response.account.PersonalDataResponse;
import com.elbis.access.wg.api.response.account.WOTAccount;
import com.elbis.action.input.ErrorMessages;
import com.elbis.action.input.ErrorsHashMap;
import com.elbis.action.search.output.SearchOutput;
import com.elbis.business.GameTypes;
import com.elbis.business.cache.CacheBean;
import com.elbis.business.controller.LanguageController;
import com.elbis.business.controller.msg.FormFields;
import com.elbis.business.manager.MessageManager;
import com.elbis.business.util.ErrorMessageUtil;

public class SearchPlayerController implements Serializable {

	private static final long serialVersionUID = 5044774140276911900L;

	private static final Logger logger = Logger
			.getLogger(SearchPlayerController.class);

	private String game = null;

	private String keyword = null;

	private LanguageController languageBean = null;

	private List<SearchOutput> outcome = null;

	private com.elbis.access.wg.api.response.account.PersonalData personalData = null;

	private String playerId = null;

	private CacheBean<com.elbis.access.wg.api.response.account.PersonalData> cacheBean;

	public String search() {
		if (GameTypes.WORLD_OF_TANKS.equals(game)) {
			outcome = searchWOTPlayer();
		} else {
			ErrorMessageUtil.addErrorMessage(
					FormFields.SEARCH_PLAYER_FORM,
					MessageManager.getErrorMessage(
							ErrorMessages.GAME_NOT_SUPPORTED,
							languageBean.getLocaleCode()).getMessage());
		}
		return null;
	}

	private List<SearchOutput> searchWOTPlayer() {
		if (keyword != null && keyword.length() > 2) {
			AccountList requestEntity = new AccountList(
					Constants.APPLICATION_ID, keyword);
			if (languageBean != null) {
				requestEntity.setLanguage(languageBean.getLocaleCode());
			}
			AccountListRequestImpl request = new AccountListRequestImpl(
					requestEntity);
			request.setMethod(com.elbis.access.Constants.HTTP_METHOD_POST);
			request.setProtocol(com.elbis.access.Constants.HTTP_PROTOCOL_HTTP);
			request.setUri(Constants.WOT_ACCOUNT_LIST);
			request.execute();
			AccountListResponse response = (AccountListResponse) request
					.updateFromResponse();
			if (Constants.RESPONSE_OK.equals(response.getStatus())) {
				List<WOTAccount> accList = response.getAccounts();
				if (accList == null || accList.isEmpty()) {
					return null;
				}
				List<SearchOutput> result = new ArrayList<SearchOutput>();
				for (WOTAccount wotAccount : accList) {
					result.add(new SearchOutput(wotAccount.getAccount_id()
							.toString(), wotAccount.getNickname()));
				}
				return result;
			} else {
				logger.error(response.getError());
				ErrorMessageUtil.addErrorMessage(MessageManager
						.getErrorMessage(ErrorMessages.WOT_API_ERROR,
								languageBean.getLocaleCode()).getMessage());
			}
		} else {
			if (logger.isInfoEnabled()) {
				logger.info(ErrorsHashMap
						.getMessage(ErrorMessages.INVALID_SEARCH_INPUT_PROVIDED));
			}
			ErrorMessageUtil.addErrorMessage(
					FormFields.SEARCH_PLAYER_FORM,
					MessageManager.getErrorMessage(
							ErrorMessages.INVALID_SEARCH_INPUT_PROVIDED,
							languageBean.getLocaleCode()).getMessage());
		}
		return null;
	}

	public void viewWOTPlayerDetails(ValueChangeEvent e) {
		playerId = e.getNewValue().toString();
		if (cacheBean.containsKey(playerId)) {
			personalData = cacheBean.get(playerId);
			return;
		}
		List<Long> accounts = new ArrayList<>();
		accounts.add(Long.valueOf(playerId));
		PersonalData requestEntity = new PersonalData(Constants.APPLICATION_ID,
				accounts);
		PersonalDataRequestImpl request = new PersonalDataRequestImpl(
				requestEntity);
		request.setUri(Constants.WOT_ACCOUNT_INFO);
		request.setMethod(com.elbis.access.Constants.HTTP_METHOD_POST);
		request.setProtocol(com.elbis.access.Constants.HTTP_PROTOCOL_HTTP);
		request.execute();
		PersonalDataResponse response = (PersonalDataResponse) request
				.updateFromResponse();
		if (Constants.RESPONSE_OK.equals(response.getStatus())) {
			if (response.getPlayerData() != null) {
				personalData = response.getPlayerData().get(playerId);
				cacheBean.put(playerId, personalData);
			}
		} else {
			logger.error(response.getError());
			ErrorMessageUtil.addErrorMessage(MessageManager.getErrorMessage(
					ErrorMessages.WOT_API_ERROR, languageBean.getLocaleCode())
					.getMessage());
		}
	}

	public void validateSearchKeyword(FacesContext ctx, UIComponent ui,
			Object value) {
		if (value == null) {
			return;
		}
		String search = (String) value;
		if (search.contains(FormFields.EMPTY_STRING)
				|| search.length() < FormFields.MIN_SEARCH_LENGTH) {
			FacesMessage msg = new FacesMessage(MessageManager.getErrorMessage(
					ErrorMessages.INVALID_SEARCH_INPUT_PROVIDED).getMessage());
			throw new ValidatorException(msg);
		}
	}

	public String getGame() {
		return game;
	}

	public void setGame(String game) {
		this.game = game;
	}

	public String getKeyword() {
		return keyword;
	}

	public void setKeyword(String keyword) {
		this.keyword = keyword;
	}

	public LanguageController getLanguageBean() {
		return languageBean;
	}

	public void setLanguageBean(LanguageController languageBean) {
		this.languageBean = languageBean;
	}

	public List<SearchOutput> getOutcome() {
		return outcome;
	}

	public void setOutcome(List<SearchOutput> result) {
		this.outcome = result;
	}

	public String getPlayerId() {
		return playerId;
	}

	public void setPlayerId(String playerId) {
		this.playerId = playerId;
	}

	public com.elbis.access.wg.api.response.account.PersonalData getPersonalData() {
		return personalData;
	}

	public CacheBean<com.elbis.access.wg.api.response.account.PersonalData> getCacheBean() {
		return cacheBean;
	}

	public void setCacheBean(
			CacheBean<com.elbis.access.wg.api.response.account.PersonalData> cacheBean) {
		this.cacheBean = cacheBean;
	}

}
